package main;

import constant.ChildWindowConstant;
import constant.CodeConstant;
import constant.Constant;
import entity.Parameters;
import entity.TablesQueryModel;
import freemarker.template.TemplateException;
import util.CodeWriterUtil;
import util.DataUtils;
import util.FreeOutUtil;
import util.ZipUtils;

import javax.swing.*;
import java.io.File;
import java.security.Key;
import java.util.HashMap;
import java.util.Map;

public class MainMethod {
	public static boolean progress(Parameters parameters) {
		String projectNameVal = parameters.getProjectNameVal();
		// projectNameVal = projectNameVal.toLowerCase();
		// 首字母大写的projectNameVal
		String captureProjectNameVal = CodeWriterUtil.captureName(projectNameVal);
		// 所选框架
		String frameWorkVal = parameters.getFrameWorkVal();
		String jsFrameWork = parameters.getJsFrameWork();
		String clientStyle = parameters.getClientFrameWorkVal();
		String clientStyleVal = clientStyle.split("-")[0];
		String dataBasePwdVal = parameters.getDataBasePwdVal();
		String dataBaseUserNameVal = parameters.getDataBaseUserNameVal();
		String dataBaseTypeVal = parameters.getDataBaseTypeVal();
		// 表名
		String tableNameVal = parameters.getTableName();
		String outPathVal = parameters.getOutPathVal();
		// 数据库url
		String dataBaseUrlVal = parameters.getDataBaseUrl();
		// 数据库driverClass
		String dataBaseDriverClassVal = parameters.getDataBaseDriverClass();
		// 登录选择
		String loginModel = parameters.getMakeModelVal();
		// 主题
		String themeVal = parameters.getThemeVal();
		//是否需要权限管理
		boolean authority = parameters.isAuthority();
		//2021-11-25
		boolean isController = parameters.isController();
		boolean isService = parameters.isService();
		boolean isDao = parameters.isDao();
		boolean isEntity = parameters.isEntity();
		boolean isView = parameters.isView();
		//2021-12-06
		String dataSourceName = parameters.getDataSourceName();
		boolean mutiDataSource = parameters.isMutiDataSource();
		try {
			// 解压
			ZipUtils.unZip(new File(Constant.modelFilesZip), Constant.modelFiles, Constant.ZIP_PWD);
			// =============================================JavaBean==========================================
			String ifJavaBean = ChildWindowConstant.tableParamConfig.get(CodeConstant.PARAM_CONFIG_KEY);
			// dao,controller,service and 公共
			Map<String, Object> root = new HashMap<>();
			// 项目名称
			root.put(CodeConstant.PROJECT_NAME, projectNameVal);
			// 首字母大写的项目名
			root.put(CodeConstant.CAPTURE_PROJECT_NAME, captureProjectNameVal);
			root.put(CodeConstant.PACKAGE_NAME, projectNameVal);
			// 框架
			root.put(CodeConstant.FRAME_WORK_VAL, frameWorkVal);
			root.put(CodeConstant.JS_FRAME_WORK, jsFrameWork);
			root.put(CodeConstant.THEME, themeVal);
			root.put(CodeConstant.CLIENT_STYLE_VAL, clientStyleVal);
			// yml
			root.put(CodeConstant.DATA_BASE_USER_NAME, dataBaseUserNameVal);
			root.put(CodeConstant.DATA_BASE_PWD, dataBasePwdVal);
			root.put(CodeConstant.DATA_BASE_URL, dataBaseUrlVal);
			root.put(CodeConstant.DATA_BASE_DRIVER_CLASS, dataBaseDriverClassVal);
			// sqlMapper
			root.put(CodeConstant.DATA_BASE_TYPE, dataBaseTypeVal);
			root.put(CodeConstant.LOGIN_MODEL, loginModel);
			// 连接池
			root.put(CodeConstant.DATABASE_POOL, ChildWindowConstant.commonParametersModel.getDatabasePool());
			// swagger2
			root.put(CodeConstant.IF_USE_SWAGGER, ChildWindowConstant.commonParametersModel.getIfUseSwagger());
			// 权限管理
			root.put(CodeConstant.IS_AUTHORITY, authority);
			//自定义模块生成
			root.put(CodeConstant.IS_CONTROLLER, isController);
			root.put(CodeConstant.IS_SERVICE, isService);
			root.put(CodeConstant.IS_DAO, isDao);
			root.put(CodeConstant.IS_ENTITY, isEntity);
			root.put(CodeConstant.IS_VIEW, isView);
			//多数据源参数
			root.put(CodeConstant.DATA_SOURCE_NAME, dataSourceName);
			root.put(CodeConstant.IS_MUTI_DATA_SOURCE, mutiDataSource);
			// --------------------
			// 全部选=全量生成 全量生成的时候才会去生成权限和登录相关代码
			if (!isController && !isService && !isDao && !isEntity && !isView) {
				//如果设置了权限管理
				if (authority) {
					//生成相关表结构，并初始化数据
					DataUtils.makeAuth(parameters);
				} else {
					//没有设置，则正常配置登录相关参数
					CodeWriterUtil.setLonginUser(loginModel, root);
				}
			}
			// --------------------
			// 项目路径配置
			String constantDir = FreeOutUtil.setProjectName(Constant.FREE_OUT_PATH_CONSTANT, projectNameVal);
			String entityDir = FreeOutUtil.setProjectName(Constant.FREE_OUT_PATH_ENTITY, projectNameVal);
			String daoDir = FreeOutUtil.setProjectName(Constant.FREE_OUT_PATH_DAO, projectNameVal);
			String serviceDir = FreeOutUtil.setProjectName(Constant.FREE_OUT_PATH_SERVICE, projectNameVal);
			String serviceImplDir = FreeOutUtil.setProjectName(Constant.FREE_OUT_PATH_SERVICE_IMPL, projectNameVal);
			String controllerDir = FreeOutUtil.setProjectName(Constant.FREE_OUT_PATH_CONTROLLER, projectNameVal);
			String coreDir = FreeOutUtil.setProjectName(Constant.FREE_OUT_PATH_CORE, projectNameVal);
			String coreAnnotationDir = FreeOutUtil.setProjectName(Constant.FREE_OUT_PATH_CORE_ANNOTATION, projectNameVal);
			String coreValidatesDir = FreeOutUtil.setProjectName(Constant.FREE_OUT_PATH_CORE_VALIDATES, projectNameVal);
			String coreExceptionDir = FreeOutUtil.setProjectName(Constant.FREE_OUT_PATH_CORE_EXCEPTION, projectNameVal);
			String dtoDir = FreeOutUtil.setProjectName(Constant.FREE_OUT_PATH_DTO, projectNameVal);
			String mutidatasourceDir = FreeOutUtil.setProjectName(Constant.MUTI_DATA_SOURCE, projectNameVal);
			// 静态资源文件，包括yml等
			String resourcesDir = FreeOutUtil.setProjectName(Constant.FREE_OUT_PATH_RESOURCES, projectNameVal);
			String sqlMapperDir = null;
			String htmlDir = null;
			// 入口文件的路径
			String mainApplicationDir = null;
			// sqlMapper和html的路径
			if ("ssm".equals(frameWorkVal)) {
				sqlMapperDir = FreeOutUtil.setProjectName(Constant.FREE_OUT_PATH_SQL_MAPPER_MVC, projectNameVal);
				htmlDir = FreeOutUtil.setProjectName(Constant.FREE_OUT_PATH_WEBINF_MVC, projectNameVal);
			} else if ("springBoot".equals(frameWorkVal)) {
				sqlMapperDir = FreeOutUtil.setProjectName(Constant.FREE_OUT_PATH_SQL_MAPPER, projectNameVal);
				htmlDir = FreeOutUtil.setProjectName(Constant.FREE_OUT_PATH_TEMPLATES, projectNameVal);
				// 入口文件的路径
				mainApplicationDir = FreeOutUtil.setProjectName(Constant.MAIN_APPLICATION_PATH, projectNameVal);
			}
			// 测试入口文件的路径
			String mainApplicationTestDir = FreeOutUtil.setProjectName(Constant.TEST_PATH, projectNameVal);
			// pom.xml的路径 .project .classpath
			String projectDir = FreeOutUtil.setProjectName(Constant.FREE_OUT_PATH, projectNameVal);
			// 工具类文件的路径
			String utilDir = FreeOutUtil.setProjectName(Constant.UTIL_PATH, projectNameVal);
			// Config的路径
			String mvcConfigDir = FreeOutUtil.setProjectName(Constant.MVC_CONFIG, projectNameVal);
			String[] tableNameArr = new String[]{};
			// 开始数据库处理===============
			if (!"".equals(tableNameVal)) {
				tableNameArr = tableNameVal.split("#");
			}
			// 生成home页面和mvc配置文件使用
			if (parameters.isMutiDataSource()) {
				//如果是多数据源
				Map<String, String> currentTableCnNameMap = new HashMap<>();
				Map<String, Map<String, TablesQueryModel>> tablesQueryMap = new HashMap<>();
				Map<String, String> tablesQueryEndAndCnMap = new HashMap<>();
				//如果是多数据源
				ChildWindowConstant.dataSourceModelMap.forEach((k, v) -> {
					currentTableCnNameMap.putAll(v.getCurrentTableCnNameMap());
					tablesQueryMap.putAll(v.getTablesQueryMap());
					tablesQueryEndAndCnMap.putAll(v.getTablesQueryEndAndCnMap());
				});
				root.put(CodeConstant.TABLE_NAME_LIST, currentTableCnNameMap);
				if (tablesQueryMap.size() != 0) {
					root.put(CodeConstant.TABLES_QUERY_MAP, tablesQueryMap);
					root.put(CodeConstant.TABLES_QUERY_END_AND_CN_MAP, tablesQueryEndAndCnMap);
				}
			} else {
				root.put(CodeConstant.TABLE_NAME_LIST, ChildWindowConstant.currentTableCnNameMap);
				// 多表配置模块
				if (ChildWindowConstant.tablesQueryMap.size() != 0) {
					root.put(CodeConstant.TABLES_QUERY_MAP, ChildWindowConstant.tablesQueryMap);
					root.put(CodeConstant.TABLES_QUERY_END_AND_CN_MAP, ChildWindowConstant.tablesQueryEndAndCnMap);
				}
			}

			// 如果是前后端分离，还需要额外创建${projectName}-webClient包，即前台页面包
			String webClientPath = "";
			String webClientHtmlPath = "";
			String webClientJsConfigPath = "";
			if (CodeConstant.H_ADMIN_THEME.equals(themeVal)) {
				webClientPath = FreeOutUtil.setWebClientName("springBoot".equals(frameWorkVal) ? Constant.WEB_CLIENT_PATH : Constant.WEB_CLIENT_PATH_MVC, projectNameVal);
				webClientHtmlPath = FreeOutUtil.setWebClientName("springBoot".equals(frameWorkVal) ? Constant.WEB_CLIENT_HTML_PATH : Constant.WEB_CLIENT_HTML_PATH_MVC, projectNameVal);
				webClientJsConfigPath = FreeOutUtil.setWebClientName("springBoot".equals(frameWorkVal) ? Constant.WEB_CLIENT_JS_CONFIG_PATH : Constant.WEB_CLIENT_JS_CONFIG_PATH_MVC, projectNameVal);
			}
			//多数据源代码生成
			if (mutiDataSource) {
				root.put(CodeConstant.DATA_SOURCE_MODEL_MAP, ChildWindowConstant.dataSourceModelMap);
				CodeWriterUtil.getMutiSourceCode(outPathVal, mutidatasourceDir, frameWorkVal, root);
			}
			// 单表代码生成
			CodeWriterUtil.getSingleTableCode(mutiDataSource, outPathVal, ifJavaBean, entityDir, daoDir, serviceDir, serviceImplDir, controllerDir, sqlMapperDir, themeVal, htmlDir, webClientHtmlPath, tableNameArr, dataBaseTypeVal, root);
			//多表代码生成
			CodeWriterUtil.getMutiTableCode(dataBaseTypeVal, mutiDataSource, outPathVal, sqlMapperDir, serviceDir, serviceImplDir, daoDir, controllerDir, themeVal, entityDir, htmlDir, webClientHtmlPath, root);
			// 生成自定义实体
			CodeWriterUtil.getMakeEntity(outPathVal, entityDir, root);
			// 下载setting.zip文件到项目路径下
			String settingsDir = FreeOutUtil.setProjectName(Constant.FREE_OUT_PATH_SETTINGS, projectNameVal);
			CodeWriterUtil.getSettingCode(root, outPathVal, frameWorkVal, settingsDir);
			String staticDir = null;
			// 如果是old 下载static.zip文件到项目路径下
			if (CodeConstant.OLD_THEME.equals(themeVal)) {
				if ("ssm".equals(frameWorkVal)) {
					staticDir = FreeOutUtil.setProjectName(Constant.FREE_OUT_PATH_STATIC_MVC, projectNameVal);
				}
				if ("springBoot".equals(frameWorkVal)) {
					staticDir = FreeOutUtil.setProjectName(Constant.FREE_OUT_PATH_STATIC, projectNameVal);
				}
			}
			CodeWriterUtil.getStaticCode(root, outPathVal, themeVal, staticDir, webClientPath);
			CodeWriterUtil.getOjdbcCode(mutiDataSource, root, outPathVal, frameWorkVal, dataBaseTypeVal, projectNameVal);
			//生成公共类
			CodeWriterUtil.getCommonCode(outPathVal, projectDir, utilDir, themeVal, htmlDir,
					webClientHtmlPath, daoDir, resourcesDir, sqlMapperDir, controllerDir, mvcConfigDir, entityDir,
					staticDir, webClientJsConfigPath, authority, root);
			if (authority) {
				//生成权限的相关代码
				CodeWriterUtil.makeAuthCode(outPathVal, utilDir, themeVal, htmlDir,
						webClientHtmlPath, daoDir, sqlMapperDir, controllerDir, serviceDir, serviceImplDir, entityDir,
						constantDir, coreAnnotationDir, coreValidatesDir, dtoDir, root);
			} else {
				//生成动态用户的相关代码
				CodeWriterUtil.getDynamicUser(outPathVal, sqlMapperDir, serviceDir, serviceImplDir, daoDir, loginModel, root);
			}
			//生成springboot的公共代码
			CodeWriterUtil.getSpringbootCommon(outPathVal, resourcesDir, mainApplicationDir, captureProjectNameVal,
					mainApplicationTestDir, mvcConfigDir, root, frameWorkVal);
			//生成springmvc的公共代码
			CodeWriterUtil.getSpringMvcCommon(outPathVal, resourcesDir, projectNameVal, htmlDir, settingsDir, mvcConfigDir, root, frameWorkVal);
			//生成core报下的response类
			CodeWriterUtil.getCoreResponse(outPathVal, coreDir, root);
			//生成core包下的annotation注解
			CodeWriterUtil.getCoreAnnotation(outPathVal, coreAnnotationDir, root);
			//生成core包下的exception
			CodeWriterUtil.getCoreException(outPathVal, coreExceptionDir, root);
		} catch (TemplateException e) {
			JOptionPane.showMessageDialog(Constant.frmv, "解析模板文件时出错！" + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
			return false;
		} catch (Exception e) {
			//TODO
			e.printStackTrace();
			JOptionPane.showMessageDialog(Constant.frmv, "生成代码时出错！" + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
			return false;
		} finally {
			// 删除model文件
			ZipUtils.deleteFiles(Constant.modelFiles);
		}
		return true;
	}
}
